<template>
  <div>
    <n-grid item-responsive responsive="screen">
      <n-gi :span="5" class="mr-4">
        <n-card title="所属部门" :segmented="{ content: true }">
          <n-input v-model:value="treeSearch" class="mb-4" clearable></n-input>
          <n-tree
            class="overflow-y-auto"
            :style="{ height: treeHeight + 'px' }"
            block-line
            selectable
            key-field="id"
            default-expand-all
            :cancelable="false"
            :pattern="treeSearch"
            :selected-keys="defaultSelectNode"
            :data="departmentTree"
            :show-irrelevant-nodes="false"
            @update:selected-keys="selectChange"
          />
        </n-card>
      </n-gi>

      <n-gi :span="19">
        <SearchForm :options="searchOptions" :hide-size="3" @search="searchFun" />
        <n-card id="user_table" class="relative overflow-hidden">
          <vxe-grid ref="sysuserRef" class="drawer_container" v-bind="gridOptions" :max-height="tableHeight">
            <template #toolbar_buttons>
              <n-button v-hasPermi="['system:user:add']" type="primary" @click="addVisible = true">新增</n-button>
              <n-button
                v-hasPermi="['system:user:add']"
                secondary
                class="m-l-2"
                type="primary"
                @click="importDataVisible = true"
              >
                导入
              </n-button>
              <n-button
                v-hasPermi="['system:user:export']"
                class="m-l-2 m-r-2"
                type="primary"
                strong
                secondary
                :disabled="exportLoading"
                :loading="exportLoading"
                @click="exportData"
              >
                导出
              </n-button>
            </template>

            <template #status="{ row, rowIndex }">
              <n-switch
                v-model:value="row.status"
                checked-value="0"
                unchecked-value="1"
                @update:value="toggleStatus(row, rowIndex)"
              >
                <template #checked>启用</template>
                <template #unchecked>停用</template>
              </n-switch>
            </template>
            <template #lockType="{ row }">
              <n-tag v-if="row.status == 0" :bordered="false" type="success">正常</n-tag>
              <n-tag v-else :bordered="false" type="error">停用</n-tag>
            </template>
            <template #sex="{ row }">
              {{ row.sex === '0' ? '男' : '女' }}
            </template>
            <template #action="{ row }">
              <n-button
                v-hasPermi="['system:user:edit']"
                quaternary
                type="info"
                size="small"
                @click="editItem(row.userId)"
              >
                修改
              </n-button>
              <n-popconfirm v-if="!row.admin" @positive-click="removeItem(row)">
                <template #trigger>
                  <n-button v-hasPermi="['system:user:remove']" quaternary type="error" size="small">删除</n-button>
                </template>
                确认删除 {{ row.userName }} 用户？
              </n-popconfirm>
              <n-dropdown
                v-if="!row.admin"
                :options="dropdownOptions"
                @select="(value: string) => moreActions({key: value, ...row})"
              >
                <n-button quaternary type="info" size="small">更多</n-button>
              </n-dropdown>
            </template>

            <template #pager>
              <vxe-pager
                v-model:current-page="searchParams.pageNum"
                v-model:page-size="searchParams.pageSize"
                :layouts="['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total']"
                :total="gridOptions.total"
                @page-change="handlePageChange"
              ></vxe-pager>
            </template>
          </vxe-grid>
        </n-card>
      </n-gi>
    </n-grid>
    <!-- 重置密码 -->
    <reset-pw :visible="resetPwVisible" :user-info="userInfo" @closed="resetPwVisible = false"></reset-pw>
    <!-- 分配角色 -->
    <reset-role :visible="resetRoleVisible" :user-id="userId" @closed="resetRoleVisible = false"></reset-role>
    <!-- 新增/编辑用户 -->
    <add-user
      :visible="addVisible"
      :dept-id="searchParams.deptId"
      :user-id="userId"
      @closed="
        () => {
          addVisible = false;
          userId = 0;
        }
      "
      @success="searchFun({})"
    ></add-user>
    <!-- 导入用户 -->
    <!-- <importData v-model:visible="importDataVisible" @import-success="importSuccess"></importData> -->
  </div>
</template>
<script lang="ts" setup>
import { useElementSizeDom } from '@/hooks';
import { exportConfig } from '@/plugins/vxeTable';
import { treeselect } from '@/service/api/system/dept';
import { changeUserStatus, delUser, listUser, SwitchUser, unlockTypeUp } from '@/service/api/system/user';
import { useAuthStore, useTabStore } from '@/store';
import { sessionStg } from '@/utils/storage';
import { Icon } from '@iconify/vue';
import type { VxeTableInstance } from 'vxe-table';
import addUser from './modules/add-user.vue';
import resetPw from './modules/reset-pw.vue';
import resetRole from './modules/reset-role.vue';

const { height: treeHeight } = useElementSizeDom(194);
const { height: tableHeight } = useElementSizeDom(164);

const userId = ref();
const importDataVisible = ref(false);

const searchOptions = reactive([
  {
    label: '登录账号',
    value: 'userName',
    type: 'input'
  },
  {
    label: '手机号码',
    value: 'phonenumber',
    type: 'input'
  },
  {
    label: '状态',
    value: 'status',
    type: 'select',
    selectOptions: [
      { label: '正常', value: 0 },
      { label: '停用', value: 1 }
    ]
  },
  {
    label: '创建时间',
    value: 'dataAry',
    valueType: 'array',
    type: 'daterange',
    rangeSplit: ['params[beginTime]', 'params[endTime]']
  }
]);

let searchParams = reactive({
  pageNum: 1,
  pageSize: 10,
  deptId: 0
});
const gridOptions = reactive<any>({
  exportConfig,
  total: 0,
  loading: false,
  data: [],
  columns: [
    { title: '用户编号', field: 'userId', width: 80 },
    { title: '用户昵称', field: 'nickName' },
    { title: '登录账号', field: 'userName' },
    { title: '部门', field: 'dept.deptName' },
    { title: '手机号码', field: 'phonenumber' },
    { title: '邮箱', field: 'email' },
    { title: '启用状态', field: 'status', width: 100, slots: { default: 'status' } },
    { title: '锁定状态', field: 'lockType', width: 80, slots: { default: 'lockType' } },
    { title: '性别', field: 'sex', width: 80, slots: { default: 'sex' } },
    { title: '最后登录时间', field: 'loginDate' },
    { title: '最后登录IP', field: 'loginIp' },
    { title: '创建时间', field: 'createTime' },
    { title: '操作', width: 200, fixed: 'right', slots: { default: 'action' } }
  ],
  toolbarConfig: {
    custom: true,
    zoom: true
  }
});

// 获取表格数据
const getTableList = async () => {
  gridOptions.loading = true;
  const { data } = await listUser(searchParams);
  gridOptions.loading = false;

  if (data) {
    gridOptions.data = data.rows;
    gridOptions.total = data.total;
  }
};

// 页码切换
const handlePageChange = (e: any) => {
  searchParams.pageNum = e.currentPage;
  searchParams.pageSize = e.pageSize;
  getTableList();
};

// 搜索/重置
const searchFun = (val?: object) => {
  searchParams.pageSize = 10;
  searchParams.pageNum = 1;
  searchParams = { ...searchParams, ...val };
  getTableList();
};

const importSuccess = () => {
  searchParams.pageNum = 1;
  searchParams.pageSize = 10;
  getTableList();
  importDataVisible.value = false;
};

// 获取部门树
const departmentTree = ref();
const defaultSelectNode = ref<number[]>([]);
const treeselectFun = async () => {
  const {data} = await treeselect();
  if (data) {
    searchParams.deptId = data[0].id;
    defaultSelectNode.value = [data[0].id];
    departmentTree.value = data;
    getTableList();
  }
};
treeselectFun();

const treeSearch = ref<string>();
const selectChange = (id: any) => {
  const _id = id[0];
  searchParams.pageNum = 1;
  searchParams.pageSize = 10;
  searchParams.deptId = _id;
  defaultSelectNode.value = [_id];
  getTableList();
};

// 编辑/新增
const addVisible = ref(false);
const editItem = (id: number) => {
  userId.value = id;
  addVisible.value = true;
};

// 切换用户状态
const toggleStatus = (row: any, rowIndex: number) => {
  const _status = row.status;
  const text = _status === '0' ? '启用' : '停用';
  window.$dialog?.warning({
    title: '提示',
    content: `确定要${text} ${row.userName}？`,
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: () => {
      changeUserStatus(row.userId, _status);
    },
    onNegativeClick: () => {
      const data: User.ListItem = gridOptions.data[rowIndex];
      data.status = _status === '0' ? '1' : '0';
    },
    onClose: () => {
      const data: User.ListItem = gridOptions.data[rowIndex];
      data.status = _status === '0' ? '1' : '0';
    },
    onMaskClick: () => {
      const data: User.ListItem = gridOptions.data[rowIndex];
      data.status = _status === '0' ? '1' : '0';
    }
  });
};

// 删除用户
const removeItem = async (row: any) => {
  const { error } = await delUser(row.userId);
  if (!error) {
    window.$message?.success('删除成功');
    searchFun({});
  }
};

// 切换用户
const auth = useAuthStore();
const toggleUser = async (row: any) => {
  if (auth.permissions && auth.permissions[0] === '*:*:*') {
    const { data } = await SwitchUser(row.userName);
    if (data) {
      sessionStg.set('switchUser', '1');
      sessionStg.set(
        'adminUserInfo',
        JSON.stringify({
          name: auth.userInfo.nickName,
          avatar: auth.userInfo!.avatar
        })
      );
      auth.toggleUserAfter(data.msg);

      // 关闭现有打开的多页签 - 因为可能切换的用户没有部分菜单权限
      const tab = useTabStore();
      tab.clearTabs();
    }
  }
};

// 解锁
const unlockTypeUpAction = async (id: number) => {
  const { error } = await unlockTypeUp(id);
  if (!error) {
    window.$message?.success('解锁成功');
  }
};

// 更多操作
const originAuth = [
  {
    label: '重置密码',
    key: 'resetPw',
    icon() {
      return h(Icon, { icon: 'ic:twotone-password' });
    }
  },
  {
    label: '分配角色',
    key: 'setRole',
    icon() {
      return h(Icon, { icon: 'fluent:people-28-filled' });
    }
  }
];
const dropdownOptions = ref<any>([]);
dropdownOptions.value = originAuth;
const adminBtnAuth = [
  {
    label: '切换到该用户',
    key: 'toogleUser',
    icon() {
      return h(Icon, { icon: 'fluent:toggle-multiple-24-filled' });
    }
  },
  {
    label: '解锁',
    key: 'unlock',
    icon() {
      return h(Icon, { icon: 'tabler:lock-off' });
    }
  }
];
const route = useRoute();
watch(
  [() => auth.permissions, () => route.fullPath],
  ([val, path]) => {
    if (path === '/system/user') {
      if (val && val[0] === '*:*:*') {
        dropdownOptions.value = [...originAuth, ...adminBtnAuth];
      } else {
        dropdownOptions.value = originAuth;
      }
    }
  },
  { immediate: true, deep: true }
);

const userInfo = ref<object>();
const resetRoleVisible = ref<boolean>(false);
const resetPwVisible = ref<boolean>(false);
const moreActions = (row: any) => {
  const { key } = row;
  switch (key) {
    case 'resetPw':
      resetPwVisible.value = true;
      userInfo.value = row;
      break;
    case 'setRole':
      resetRoleVisible.value = true;
      userId.value = row.userId;
      break;
    case 'toogleUser':
      if (row.admin) {
        window.$message?.warning('请切换至非管理员角色');
        return;
      }
      toggleUser(row);
      break;
    case 'unlock':
      unlockTypeUpAction(row.userId);
      break;
    default:
  }
};

// 导出
const sysuserRef = ref<VxeTableInstance>();
const exportLoading = ref<boolean>(false);
const exportData = async () => {
  exportLoading.value = true;
  const { data } = await listUser({ ...searchParams, pageSize: gridOptions.total, pageNum: 1 });
  exportLoading.value = false;
  if (data) {
    sysuserRef.value!.openExport({
      type: 'xlsx',
      mode: 'all',
      modes: ['all'],
      isMerge: true,
      useStyle: true,
      isColgroup: true,
      sheetName: 'Sheet1',
      filename: '用户表',
      data: gridOptions.data
    });
  }
};
</script>
